package fr.upmc.i3s.upmcontact.views.fragments;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import fr.upmc.i3s.upmcontact.Constants;
import fr.upmc.i3s.upmcontact.R;
import fr.upmc.i3s.upmcontact.backend.BackEndBridgeImpl;
import fr.upmc.i3s.upmcontact.callbacks.IPickerCallback;
import fr.upmc.i3s.upmcontact.callbacks.IPostDataCallback;
import fr.upmc.i3s.upmcontact.contents.Incident;
import fr.upmc.i3s.upmcontact.tools.BitmapFactoryAdapter;
import fr.upmc.i3s.upmcontact.tools.PickerDialogFactory;
import fr.upmc.i3s.upmcontact.tools.PreferencesManager;
import fr.upmc.i3s.upmcontact.tools.StringUtils;
import fr.upmc.i3s.upmcontact.tools.UriUtils;
import fr.upmc.i3s.upmcontact.views.FragmentController;
import fr.upmc.i3s.upmcontact.views.fragments.models.IFragmentModel;
import fr.upmc.i3s.upmcontact.views.fragments.models.PageFragmentModel;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class ReportIncidentFragment extends PageFragmentModel implements IFragmentModel {
	
	private static final String TAG = "ReportIncidentFragment";
	
	private static final int PICTURE_REQUEST = 1991;
	
	private FragmentController fragmentController;
	private static volatile ReportIncidentFragment INSTANCE;
	
	private EditText etPlace;
	private EditText etType;
	private EditText etDescription;
	private EditText etPriority;
	private ImageView ivShowPhoto;
	private ImageView ivAddPhoto;
	private Button bReport;
	private TextView tvFeetLeft;
	private TextView tvFeetRight;
	private ImageView ivArrowLeft;
	private ImageView ivArrowRight;
	
	private int selectedType;
	private int selectedPriority;
	private Uri capturedImageUri;
	private boolean hasPhoto;
	
	public static ReportIncidentFragment getInstance() {
		if(INSTANCE == null) {
			ReportIncidentFragment fragment = new ReportIncidentFragment();
		    Bundle bundle = new Bundle(3);
		    bundle.putInt(EXTRA_LAYOUT_FRAGMENT, R.layout.fragment_report_incident);
		    bundle.putInt(EXTRA_HEAD_ICON, R.drawable.ic_menu_incident_white);
		    bundle.putInt(EXTRA_HEAD_TEXT, R.string.title_fragment_incidents);
		    fragment.setArguments(bundle);
		    INSTANCE = fragment;
		}
		return INSTANCE;
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		return super.onCreateView(inflater, container, savedInstanceState);
	}
	
 	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.initFragmentViews();
		this.fragmentController = (FragmentController) getActivity();
		this.hasPhoto = false;
		fetchViews();
		customizeViews();
		setListeners();
	}
 	
 	@Override
 	public void fetchViews() {
 		this.etPlace = (EditText) this.getView().findViewById(R.id.editText_place);
 		this.etType = (EditText) this.getView().findViewById(R.id.editText_type);
 		this.etDescription = (EditText) this.getView().findViewById(R.id.editText_description);
 		this.etPriority = (EditText) this.getView().findViewById(R.id.editText_priority);
 		this.ivShowPhoto = (ImageView) this.getView().findViewById(R.id.imageView_show_photo);
 		this.ivAddPhoto = (ImageView) this.getView().findViewById(R.id.imageView_add_photo);
 		this.bReport = (Button) this.getView().findViewById(R.id.button_report);
 		this.tvFeetLeft = (TextView) this.getView().findViewById(R.id.textView_feet_text_left);
 		this.tvFeetRight = (TextView) this.getView().findViewById(R.id.textView_feet_text_right);
 		this.ivArrowLeft = (ImageView) this.getView().findViewById(R.id.imageView_feet_arrow_left);
 		this.ivArrowRight = (ImageView) this.getView().findViewById(R.id.imageView_feet_arrow_right);
 	}
 	
 	@Override
 	public void customizeViews() {
 		this.tvFeetLeft.setText("");
 		this.tvFeetRight.setText("");
 		this.ivArrowLeft.setVisibility(View.GONE);
 		this.ivArrowRight.setVisibility(View.GONE);
 		if(hasPhoto) {
			Bitmap bm = BitmapFactoryAdapter.decodeUri(capturedImageUri, 250);
			this.ivShowPhoto.setImageBitmap(bm);
 		}
 	}
 	
 	@Override
 	public void setListeners() {
 		this.etType.setOnTouchListener(onTypeTouchedListener);
 		this.etPriority.setOnTouchListener(onPriorityTouchedListener);
 		this.ivAddPhoto.setOnClickListener(onAddPhotoClickListener);
 		this.bReport.setOnClickListener(onReportClickListener);
 	}
 	
	@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {  
		if(requestCode == PICTURE_REQUEST && resultCode == Activity.RESULT_OK) {
			final boolean isCamera;
			if(data == null) {
				isCamera = true;
			} else {
				final String action = data.getAction();
				if(action == null) {
					isCamera = false;
				} else {
					isCamera = action.equals(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
				}
			}
			if(isCamera) {
				this.hasPhoto = true;
				Bitmap bm = BitmapFactoryAdapter.decodeUri(capturedImageUri, 250);
				this.ivShowPhoto.setImageBitmap(bm);
			} else {
				if(data != null) {
					this.hasPhoto = true;
					capturedImageUri = UriUtils.convertMediaUriToFileUri(fragmentController, data.getData());
					Bitmap bm = BitmapFactoryAdapter.decodeUri(capturedImageUri, 250);
					this.ivShowPhoto.setImageBitmap(bm);
				}
			}
			Log.d(TAG, "onActivityResult.isCamera="+isCamera+", capturedImageUri="+capturedImageUri);
		}
	}

 	
	  ///////////////
	 // CALLBACKS //
	///////////////
	
	private IPickerCallback pickTypeCallback = new IPickerCallback() {
		@Override
		public void perform(int state, int picked, String label) {
			switch(state) {
			case PickerDialogFactory.STAND_BY_LISTENER:
				etType.setOnTouchListener(null);
				break;
			case PickerDialogFactory.PICKED:
				etType.setText(label);
				selectedType = picked;
				etType.setOnTouchListener(onTypeTouchedListener);
				break;
			case PickerDialogFactory.CANCELED:
				etType.setOnTouchListener(onTypeTouchedListener);
				break;
			}
		}
	};
	
	
	private IPickerCallback pickPriorityCallback = new IPickerCallback() {
		@Override
		public void perform(int state, int picked, String label) {
			switch(state) {
			case PickerDialogFactory.STAND_BY_LISTENER:
				etPriority.setOnTouchListener(null);
				break;
			case PickerDialogFactory.PICKED:
				etPriority.setText(label);
				selectedPriority = picked;
				etPriority.setOnTouchListener(onPriorityTouchedListener);
				break;
			case PickerDialogFactory.CANCELED:
				etPriority.setOnTouchListener(onPriorityTouchedListener);
				break;
			}
		}
	};
	
	private IPostDataCallback incidentPostedCallback = new IPostDataCallback() {
		@Override
		public void posted(boolean success) {
			if(success) {
				PreferencesManager.incrementIncidentReportStatistics(fragmentController);
				selectedType = 0;
				selectedPriority = 0;
				capturedImageUri = null;
				hasPhoto = false;
				etPlace.setText("");
				etDescription.setText("");
				etType.setText("");
				etPriority.setText("");
				ivShowPhoto.setImageBitmap(null);
				ivShowPhoto.setImageDrawable(fragmentController.getResources().getDrawable(R.drawable.ph_incident));
			}
			fragmentController.switchContent(
					ThanksFragment.newInstance(0, R.string.display_thanks_incident), 
					FragmentController.TRANSACTION_FROM_RIGHT_TO_LEFT);
	 		// re-use dialog in backendbridge
			BackEndBridgeImpl.getInstance(fragmentController).setCancelForAWhile(false);
		}
	};
	
	
	  ///////////////
	 // LISTENERS //
	///////////////
 	
 	private OnTouchListener onTypeTouchedListener = new OnTouchListener() {
		@Override
		public boolean onTouch(View view, MotionEvent event) {
			String[] types_names = getResources().getStringArray(R.array.incident_type_names);
			int nbTypeNames = getResources().getInteger(R.integer.nb_type_names);
			PickerDialogFactory.createStringPickerForView(
					fragmentController, fragmentController.getString(R.string.prompt_type), 
					0, nbTypeNames-1, selectedType,
					types_names, pickTypeCallback).show();
			return false;
		}
 	};
 	
 	private OnTouchListener onPriorityTouchedListener = new OnTouchListener() {
		@Override
		public boolean onTouch(View view, MotionEvent event) {
			String[] priority_names = getResources().getStringArray(R.array.incident_priority_names);
			int nbPriorityNames = getResources().getInteger(R.integer.nb_priority_names);
			PickerDialogFactory.createStringPickerForView(
					fragmentController, fragmentController.getString(R.string.prompt_priority), 
					0, nbPriorityNames-1, selectedPriority,
					priority_names, pickPriorityCallback).show();
			return false;
		}
 	};
 	
 	private OnClickListener onAddPhotoClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			final File root = new File(Constants.INCIDENTS_EXTERNAL_FOLDER);
			final String fname = StringUtils.generateRandomString(12)+".jpg";
			final File sdImageMainDirectory = new File(root, fname);
			capturedImageUri = Uri.fromFile(sdImageMainDirectory);
			// camera intent :
			final List<Intent> cameraIntents = new ArrayList<Intent>();
			final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
			final PackageManager packageManager = fragmentController.getPackageManager();
			final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
			for(ResolveInfo res : listCam) {
				final String packageName = res.activityInfo.packageName;
				final Intent intent = new Intent(captureIntent);
				intent.setComponent(new ComponentName(res.activityInfo.packageName, res.activityInfo.name));
				intent.setPackage(packageName);
				intent.putExtra(MediaStore.EXTRA_OUTPUT, capturedImageUri);
				cameraIntents.add(intent);
			}
			// filesystem intent :
			final Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
//			final Intent galleryIntent = new Intent();
//			galleryIntent.setType("image/*");
//			galleryIntent.setAction(Intent.ACTION_GET_CONTENT);
			// chooser of filesystem options intent :
			final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
			// add the camera options :
			chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[]{}));
			// start activity for result :
			startActivityForResult(chooserIntent, PICTURE_REQUEST);
		}
 	};
 	
 	private OnClickListener onReportClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			String place = etPlace.getText().toString();
			if(place == null || place.equals("") || place.equals(" ")) {
				etPlace.setHint(R.string.error_wrong_place);
				etPlace.setHintTextColor(Color.RED);
				return;
			}
			String type = etType.getText().toString();
			if(type == null || type.equals("") || type.equals(" ")) {
				etType.setHint(R.string.error_wrong_type);
				etType.setHintTextColor(Color.RED);
				return;
			}
			String description = etDescription.getText().toString();
			if(description == null || description.equals("") || description.equals(" ")) {
				etDescription.setHint(R.string.error_wrong_description);
				etDescription.setHintTextColor(Color.RED);
				return;
			}
			String priority = etPriority.getText().toString();
			if(priority == null || priority.equals("") || priority.equals(" ")) {
				etPriority.setHint(R.string.error_wrong_priority);
				etPriority.setHintTextColor(Color.RED);
				return;
			}
			String photoPath = null;
			if(hasPhoto) {
				photoPath = StringUtils.getRealPathFromURI(fragmentController, capturedImageUri);
			}
			
			Incident incident = new Incident(null, null, null, 
												description, place, photoPath, BackEndBridgeImpl.getInstance(fragmentController).getCurrentUser(),
												selectedType, selectedPriority, BackEndBridgeImpl.PARSE_INCIDENT_STATUS_SIGNALED);
						
			BackEndBridgeImpl.getInstance(fragmentController).postIncident(incident, incidentPostedCallback);
		}
	};
	
}
